package com.water.wfo.component.util;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * packageName com.water.wfo.component.util
 *
 * @author junhuili
 * @version JDK 8
 * @date 2024/5/28
 * @description TODO
 */
@Slf4j
public class ThreadPoolUtil {

    private ThreadPoolUtil() {
    }

    /**
     * 线程池 最小数量
     */
    private static final int COREPOOLSIZE = 20;

    /**
     * 线程池 最大数量
     */
    private static final int MAXIMUMPOOLSIZE = 60;

    /**
     * 保持活跃时间
     */
    private static final long KEEPALIVVETIME = 60000L;

    /**
     * 线程名称
     */
    private static ThreadFactory takThreadFactory = new ThreadFactoryBuilder().setNameFormat("wfo-thread-pool-util-%d").build();

    /**
     * 线程池
     */
    private static final ExecutorService EXECUTOR_SERVICE = new ThreadPoolExecutor(
            COREPOOLSIZE, MAXIMUMPOOLSIZE, KEEPALIVVETIME, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>(), takThreadFactory,
            new ThreadPoolExecutor.AbortPolicy());

    public static Executor getExecutorService() {
        return EXECUTOR_SERVICE;
    }

    /**
     * 线程执行
     *
     * @param runnable
     */
    public static void execute(Runnable runnable) {
        EXECUTOR_SERVICE.execute(runnable);
    }

    /**
     * 添加多个线程
     *
     * @param commands
     */
    public static void execute(List<Runnable> commands) {
        for (Runnable runnable : commands) {
            execute(runnable);
        }
    }

    /**
     * 线程执行
     *
     * @param task
     */
    public static <T> Future<T> submit(Callable<T> task) {
        return EXECUTOR_SERVICE.submit(task);
    }

    /**
     * 线程执行
     *
     * @param task
     */
    public static <T> T invoke(Callable<T> task) {
        Future<T> future = EXECUTOR_SERVICE.submit(task);
        try {
            return future.get();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 多线程处理异步任务并返回结果
     *
     * @param tasks
     * @param <T>
     * @return
     */
    public static <T> List<T> invokeAll(List<Callable<T>> tasks) {
        List<Future<T>> futureList;
        List<T> results = null;
        try {
            futureList = EXECUTOR_SERVICE.invokeAll(tasks);
            results = new ArrayList<>();
            for (Future<T> future : futureList) {
                results.add(future.get());
            }
        } catch (Exception e) {
            log.error("多线程处理异步任务异常", e);
        }
        return results;
    }

    /**
     * 多线程处理异步任务并返回结果
     *
     * @param tasks
     * @param <T>
     * @return
     */
    public static <T> List<T> invokeAllTask(List<Callable<T>> tasks) throws ExecutionException, InterruptedException {
        List<Future<T>> futureList = EXECUTOR_SERVICE.invokeAll(tasks);
        List<T> results = new ArrayList<>();
        for (Future<T> future : futureList) {
            results.add(future.get());
        }
        return results;
    }
}
